

#include "Protocolo_NIPC.h"


int32_t handshakePPD(int32_t socket, char* identificador_disco) {
	paquete *NIPC;
	NIPC = (paquete*) malloc(sizeof(paquete));
	NIPC->type = 0;
	NIPC->payload_Length = strlen(identificador_disco) + 1;
	NIPC->nro_Sector = configuracion.cilindro * configuracion.cabeza * configuracion.sector;
	strcpy(NIPC->payload, identificador_disco);
	send(socket, NIPC, sizeof(paquete), 0);
	free(NIPC);
	paquete *recibirNIPC;
	recibirNIPC = (paquete*) malloc(sizeof(paquete));
	int length_recibido, resultado_operacion;
	length_recibido = recv(socket, recibirNIPC, sizeof(paquete), MSG_WAITALL);
	if (recibirNIPC->type == 0 && recibirNIPC->payload_Length == 0) {
		resultado_operacion = 0; /* la conexion fue exitosa */
	} else {
		if (recibirNIPC->type == 0 && recibirNIPC->payload_Length != 0) {
			resultado_operacion = 1;
			printf("%s", (char*) recibirNIPC->payload);
		}
	}
	return resultado_operacion;
}

int32_t handshakePRAID_PPD(int32_t socket, paquete *NIPC) {
	paquete *enviarNIPC;
	int32_t resultado;
	enviarNIPC = (paquete*) malloc(sizeof(paquete));
	if (NIPC->type == 0) {
		enviarNIPC->type = 0;
		strcpy(enviarNIPC->payload, "");
		enviarNIPC->payload_Length = strlen(enviarNIPC->payload); /*si la conexion es correcta */
		send(socket, enviarNIPC, sizeof(paquete), 0);
		resultado = 1;
		return resultado;
	} else { /*si la conexion es incorrecta */
		enviarNIPC->type = 0;
		strcpy(enviarNIPC->payload, "Se produjo un error en la conexion\n");
		enviarNIPC->payload_Length = strlen(enviarNIPC->payload);
		send(socket, enviarNIPC, sizeof(paquete), 0);
		close(socket);
	}
	resultado = 1;
	return resultado;
}

int32_t handshakeFS_PPD(int32_t socket, int32_t type){
	paquete *enviarNIPC;
	int32_t resul;
	enviarNIPC = (paquete*)malloc(sizeof(paquete));
	enviarNIPC->nro_Sector=0;
	if(type==0){
		enviarNIPC->type = 0;
		strcpy(enviarNIPC->payload,"todo bien puto");/*si la conexion es correcta */
		enviarNIPC->payload_Length = 0;

		send(socket, enviarNIPC, sizeof(paquete), 0);
		resul=0;
	}
	else{                                             /* si la conexion es incorrecta */
		enviarNIPC->type = 0;
		strcpy(enviarNIPC->payload,"Se produjo un error en la conexion\n");
		enviarNIPC->payload_Length = strlen(enviarNIPC->payload);
		send(socket, enviarNIPC, sizeof(paquete), 0);
        resul=1;
	}
	return resul;
}

int32_t conectarse_RAID(char* DIRECCION_IP, uint16_t PUERTO,
		char* IDENTIFICADOR_DISCO)

{

	uint8_t sockfd, handshake_OK;
	paquete *NIPC_Prueba;
	NIPC_Prueba = (paquete *) malloc(sizeof(paquete));
	int len;
	struct sockaddr_in address;
	int result;

	/* Crear un socket para el cliente */

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd==-1){
		printf("El socket no se pudo crear\n");
		return -1;
	}
	printf("El socket se creo bien\n");
	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET;
	address.sin_addr.s_addr = inet_addr(DIRECCION_IP);
	address.sin_port = PUERTO;
	len = sizeof(address);

	int8_t valor;
	int32_t optval=1;
	valor = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(int32_t));
	if (valor==-1)perror("setsocktp:");

	result = connect(sockfd, (struct sockaddr *) &address, len);

	if (result == -1) {
		perror("ERROR EN LA CONEXION");
		exit(1);
	}

	handshake_OK = handshakePPD(sockfd, IDENTIFICADOR_DISCO);

	if (handshake_OK){
		perror("Handshake: ");
		close(sockfd);
		exit(1);
	}
	printf("Handshake correcto\n");
	return sockfd;
}

void enviarSector(t_sector sector){
	paquete *NIPC;
	NIPC = (paquete*) malloc(sizeof(paquete));
	memcpy(NIPC->payload,sector.datos,512);
	NIPC->nro_Sector = obtener_dir_log(sector.direccion);
	NIPC->type = sector.type;
	NIPC->payload_Length=512;
	int enviados=0;

	enviados=send(sector.sock, NIPC, sizeof(paquete), 0);
	if((enviados==-1)||(enviados!=sizeof(paquete))){perror("send)");};
	free(NIPC);
}

t_sector recibirSector(int32_t socket){
	t_sector sector;
	paquete *NIPC;
	NIPC = (paquete*) malloc(sizeof(paquete));
	if(recv(socket, NIPC, sizeof(paquete), MSG_WAITALL)==-1)
	{
		printf("Error en recibir pedidos del socket %d\n",socket);
		perror("recv:");
		sector.type = -1;
	}
	else
	{
		memcpy(sector.datos, NIPC->payload, 512);
		sector.type = NIPC->type;
		sector.direccion = obtener_dir_fis(NIPC->nro_Sector);
		sector.sock = socket;
	}
	free(NIPC);
	return sector;
}

int32_t conectarse_FS(char* DIRECCION_IP,uint16_t PUERTO,char* IDENTIFICADOR_DISCO){
	int32_t server_sockfd;
	uint32_t server_len;
	int8_t valor;
	struct sockaddr_in server_address;
	server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
	int32_t optval=1;
	valor = setsockopt(server_sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(int32_t));
	if (valor==-1)perror("setsocktp:");
	memset(&server_address, 0, sizeof(server_address));
	server_address.sin_family = AF_INET;
	server_address.sin_addr.s_addr = inet_addr(DIRECCION_IP);
	server_address.sin_port = PUERTO;
	server_len = sizeof(server_address);
	if(bind(server_sockfd, (struct sockaddr *) &server_address, server_len)==-1)
		perror("bind");
	if(listen(server_sockfd, 1)==-1)
		perror("listen");
	return server_sockfd;
}
